package com.ray.finance.strategy.bill.create;

import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.ray.business.check.SaleCheck;
import com.ray.business.enums.PurchaseInStatusEnum;
import com.ray.business.service.ProdSaleBackService;
import com.ray.business.service.ProdSaleService;
import com.ray.business.table.entity.ProdSale;
import com.ray.business.table.entity.ProdSaleBack;
import com.ray.finance.builder.BillBuilder;
import com.ray.finance.enums.BillSourceEnum;
import com.ray.finance.enums.BillStatusEnum;
import com.ray.finance.enums.BillTypeEnum;
import com.ray.finance.service.FinaBillService;
import com.ray.finance.table.entity.FinaBill;
import com.ray.finance.table.params.bill.BillCreateParams;
import com.ray.magicBlock.Strategy;
import com.ray.magicBlock.anno.Block;
import com.ray.woodencreate.beans.LoginUser;
import com.ray.woodencreate.exception.BusinessExceptionFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;

/**
 * @author bo shen
 * @Description: 对账单
 * @Class: SaleInService
 * @Package com.ray.wms.strategy.in
 * @date 2020/6/8 15:05
 * @company <p>Ray快速开发平台</p>
 * @updateRecord time(修改时间)  author(修改人)   desc(修改内容)
 */
@Slf4j
@Block(group = "createBill", strategy = "SALE", desc = "销售对账单")
public class SaleCreateService implements Strategy<BillCreateParams, LoginUser, String> {

    @Autowired
    private ProdSaleService prodSaleService;
    @Autowired
    private ProdSaleBackService prodSaleBackService;
    @Autowired
    private FinaBillService finaBillService;

    @Override
    public String execute(BillCreateParams createParams, LoginUser loginUser) {
        //查询采购单列表
        List<String> orderNos = createParams.getOrderNos();
        List<ProdSale> prodSales = prodSaleService.listByOrderNos(createParams.getOrderNos(), loginUser);
        if (ObjectUtil.isEmpty(prodSales) || prodSales.size() != orderNos.size()) {
            log.info("查询到的采购单数量与订单接口数量不一致,参数：{},结果:{}", orderNos.size(), prodSales.size());
            throw BusinessExceptionFactory.newException("采购单数量与订单接口数量不一致");
        }
        //客户数据
        String customerCode = null;

        //总金额
        BigDecimal total = new BigDecimal(0);
        for (ProdSale prodSale : prodSales) {
            if (StrUtil.isBlank(customerCode)) {
                customerCode = prodSale.getCustomerCode();
            }
            new SaleCheck(prodSale).checkNull("").canBill(String.format("订单[%s]不能对账", prodSale.getOrderNo()));
            if (!StrUtil.equals(customerCode, prodSale.getCustomerCode())) {
                log.info("客户不一致");
                throw BusinessExceptionFactory.newException("客户不一致");
            }
            total = total.add(NumberUtil.null2Zero(prodSale.getTotalAmount()));
        }
        //查询是否有未完成的退款单
        Integer count = prodSaleBackService.countByOrderNos(orderNos, Arrays.asList(PurchaseInStatusEnum.UN_CHECK.getValue(), PurchaseInStatusEnum.UN_IN.getValue()), loginUser);
        if (count > 0) {
            log.info("存在操作完成的退回单");
            throw BusinessExceptionFactory.newException("存在操作完成的退回单");
        }
        //查询退款金额
        List<ProdSaleBack> prodSaleBacks = prodSaleBackService.listByOrderNos(orderNos, Arrays.asList(PurchaseInStatusEnum.FINISH.getValue()), loginUser);

        BigDecimal deduction = new BigDecimal(0);
        if (ObjectUtil.isNotEmpty(prodSaleBacks)) {
            deduction = prodSaleBacks.stream().map(ProdSaleBack::getTotalAmount).reduce(BigDecimal::add).get();
        }
        //查询订单信息的币种信息
        String currency = prodSaleService.queryOrderCurrency(orderNos, loginUser);

        BillBuilder billBuilder = new BillBuilder();
        billBuilder.appendCreate(loginUser).appendOrderStatus(BillStatusEnum.UN_CHECK.getValue());
        FinaBill finaBill = billBuilder.bulid();
        finaBill.setTotalAmount(total);
        finaBill.setDeductionAmount(deduction);
        finaBill.setAmount(total.subtract(deduction));
        finaBill.setCustomerCode(customerCode);
        finaBill.setCurrency(currency);
        finaBill.setBillType(BillTypeEnum.IN.getValue());
        finaBill.setBillSource(BillSourceEnum.SALE.getValue());
        //保存
        finaBillService.save(finaBill);
        //保存关联
        if (!prodSaleService.comfireBill(orderNos, billBuilder.getCode(), loginUser)) {
            throw BusinessExceptionFactory.newException("完成销售对账异常");
        }
        if (prodSaleBackService.countBill(orderNos, loginUser) > 0) {
            if (!prodSaleBackService.comfireBill(orderNos, billBuilder.getCode(), loginUser)) {
                throw BusinessExceptionFactory.newException("完成销售退货对账异常");
            }
        }
        return billBuilder.getCode();
    }
}
